package hr.ctg.domain.action.objekt;

import hr.ctg.domain.action.SlikaAction;
import hr.ctg.domain.model.Adresa;
import hr.ctg.domain.model.Cijena;
import hr.ctg.domain.model.DnevnikAktivnosti;
import hr.ctg.domain.model.Drzava;
import hr.ctg.domain.model.EmailAdresa;
import hr.ctg.domain.model.Jezik;
import hr.ctg.domain.model.Kategorija;
import hr.ctg.domain.model.Korisnik;
import hr.ctg.domain.model.Mjesto;
import hr.ctg.domain.model.Objekt;
import hr.ctg.domain.model.Opis;
import hr.ctg.domain.model.Osobina;
import hr.ctg.domain.model.Posjet;
import hr.ctg.domain.model.Posta;
import hr.ctg.domain.model.Slika;
import hr.ctg.domain.model.Smjestaj;
import hr.ctg.domain.model.Telefon;
import hr.ctg.domain.model.TipAdrese;
import hr.ctg.domain.model.TipEmailAdrese;
import hr.ctg.domain.model.TipObjekta;
import hr.ctg.domain.model.TipTelefona;
import hr.ctg.domain.model.Zupanija;
import hr.ctg.domain.model.Rola.Role;
import hr.ctg.service.dao.AdresaDAO;
import hr.ctg.service.dao.AkcijaDAO;
import hr.ctg.service.dao.CijenaDAO;
import hr.ctg.service.dao.DnevnikAktivnostiDAO;
import hr.ctg.service.dao.EmailAdresaDAO;
import hr.ctg.service.dao.JezikDAO;
import hr.ctg.service.dao.KategorijaDAO;
import hr.ctg.service.dao.MjestoDAO;
import hr.ctg.service.dao.ObjektDAO;
import hr.ctg.service.dao.OpisDAO;
import hr.ctg.service.dao.OsobinaDAO;
import hr.ctg.service.dao.PosjetDAO;
import hr.ctg.service.dao.PostaDAO;
import hr.ctg.service.dao.SlikaDAO;
import hr.ctg.service.dao.SmjestajDAO;
import hr.ctg.service.dao.TelefonDAO;
import hr.ctg.service.dao.TipAdreseDAO;
import hr.ctg.service.dao.TipEmailAdreseDAO;
import hr.ctg.service.dao.TipObjektaDAO;
import hr.ctg.service.dao.TipTelefonaDAO;
import hr.ctg.service.dao.ZupanijaDAO;
import hr.ctg.util.CacheUtil;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.faces.component.UISelectItems;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.cache.CacheProvider;
import org.jboss.seam.faces.FacesMessages;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Identity;
import org.jboss.seam.ui.component.html.HtmlSelectItems;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

@Scope(ScopeType.CONVERSATION)
@Name(value = "objektSuggest")
public class ObjektSuggestAction {
	@Logger
	Log log;
	@In
	FacesMessages facesMessages;

	@SuppressWarnings("unchecked")
	@In
	CacheProvider cacheProvider;

	@In
	private KategorijaDAO kategorijaDAO;
	@In
	private JezikDAO jezikDAO;
	@In
	private ObjektDAO objektDAO;
	@In
	PostaDAO postaDAO;
	@In
	MjestoDAO mjestoDAO;
	@In
	ZupanijaDAO zupanijaDAO;
	@In
	AkcijaDAO akcijaDAO;
	@In
	DnevnikAktivnostiDAO dnevnikAktivnostiDAO;
	@In
	SlikaDAO slikaDAO;
	@In
	OpisDAO opisDAO;
	@In
	TelefonDAO telefonDAO;
	@In
	AdresaDAO adresaDAO;
	@In
	EmailAdresaDAO emailAdresaDAO;
	@In
	CijenaDAO cijenaDAO;
	@In
	OsobinaDAO osobinaDAO;
	@In
	TipObjektaDAO tipObjektaDAO;
	@In
	TipAdreseDAO tipAdreseDAO;
	@In
	TipTelefonaDAO tipTelefonaDAO;
	@In
	TipEmailAdreseDAO tipEmailAdreseDAO;
	@In
	SmjestajDAO smjestajDAO;
	@In
	Identity identity;
	@In
	String currentLang;
	@In(create = true)
	SlikaAction slikaAction;

	@In(required = false)
	Korisnik korisnik;
	@In
	PosjetDAO posjetDAO;

	@Out
	private int suggestStep = 1;

	private List<TipObjekta> tipoviObjekta;
	private List<Zupanija> zupanijeObjekta;
	private final List<Mjesto> mjestaObjekta = new ArrayList<Mjesto>();
	private List<TipAdrese> tipoviAdrese;
	private List<TipTelefona> tipoviTelefona;
	private List<TipEmailAdrese> tipoviEmailAdrese;
	private List<Osobina> osobine;
	private final List<Posta> posteAdrese = new ArrayList<Posta>();
	private final List<Mjesto> mjestaAdrese = new ArrayList<Mjesto>();
	private List<Cijena> cijene = new ArrayList<Cijena>();
	private List<Telefon> uneseniTelefoni;
	private List<EmailAdresa> uneseneEmailAdrese;
	private List<Adresa> uneseneAdrese;
	private List<Slika> uneseneSlike;
	private List<Opis> uneseniOpisi;
	private List<Kategorija> kategorije;
	private List<Jezik> jezici;

	private Objekt objekt = new Objekt();
	private Adresa adresa = new Adresa();
	private Telefon telefon = new Telefon();
	private Mjesto mjesto = new Mjesto();
	private TipObjekta tipObjekta = new TipObjekta();
	private EmailAdresa emailAdresa = new EmailAdresa();
	private Smjestaj smjestaj = new Smjestaj();
	private Slika slika = new Slika();
	private Opis opisObjekta = new Opis();
	private Cijena cijena = new Cijena();
	private final Map<Integer, Boolean> osobineMap = new HashMap<Integer, Boolean>();
	private String latituda;
	private String longituda;
	private int zoom;

	private Posta posta;
	private Zupanija zupanija;
	private Kategorija kategorija;
	private boolean editMode = false;
	private boolean otherUserImagesPresent = false;

	@In(required = false, create = true)
	@Out(required = false)
	SuggestObjektComponents soComponents;
	@RequestParameter
	private Integer idObjekta;

	private String back;

	@Create
	public void init() {
		zoom = 6;
		latituda = Double.toString(Drzava.CRO_LATITUDA);
		longituda = Double.toString(Drzava.CRO_LONGITUDA);
	}

	public String step1() {
		log.error("Prilagodba za korak " + suggestStep);
		suggestStep = 1;
		soComponents.setPosteObjekta(new HtmlSelectItems());
		final List<Posta> poste = postaDAO.findAllInZupanija(zupanija
				.getIdZupanje());

		soComponents.getPosteObjekta().setValue(poste);
		return "switch";
	}

	public String previousStep() {
		suggestStep--;
		if (1 == suggestStep)
			step1();
		log.error("idem u korak:" + suggestStep);
		return "switch";
	}

	public String nextStep() {
		suggestStep++;
		log.error("idem u korak:" + suggestStep);
		return "next";
	}

	public String switchToStep(int step) {
		suggestStep = step;
		if (1 == suggestStep)
			step1();
		log.error("switch u korak:" + suggestStep);
		return "switch";
	}

	public void loadPage() {
		log.debug("Prikazujem stranicu a bean je: " + this);

	}

	public List<TipObjekta> getTipoviObjekta() {
		if (null == tipoviObjekta) {
			tipoviObjekta = tipObjektaDAO.findAll();
		}
		return tipoviObjekta;
	}

	public List<Kategorija> getKategorije() {
		if (null == kategorije) {
			kategorije = kategorijaDAO.findAll();
		}
		return kategorije;
	}

	public List<Jezik> getJezici() {
		if (null == jezici) {
			jezici = jezikDAO.findAll();
		}
		return jezici;
	}

	public List<Zupanija> getZupanijeObjekta() {
		if (null == zupanijeObjekta) {
			zupanijeObjekta = zupanijaDAO.findAll();
		}
		return zupanijeObjekta;
	}

	public List<Mjesto> getMjestaObjekta() {
		return mjestaObjekta;
	}

	public List<TipAdrese> getTipoviAdrese() {
		if (null == tipoviAdrese) {
			tipoviAdrese = tipAdreseDAO.findAll();
		}
		return tipoviAdrese;
	}

	public List<TipTelefona> getTipoviTelefona() {
		if (null == tipoviTelefona) {
			tipoviTelefona = tipTelefonaDAO.findAll();
		}
		return tipoviTelefona;
	}

	public List<TipEmailAdrese> getTipoviEmailAdrese() {
		if (null == tipoviEmailAdrese) {
			tipoviEmailAdrese = tipEmailAdreseDAO.findAll();
		}
		return tipoviEmailAdrese;
	}

	public List<Osobina> getOsobine() {
		// if (null == osobine) {
		osobine = osobinaDAO.findByIdTipaObjekta(tipObjekta.getIdTipaObjekta());
		// }
		return osobine;
	}

	Map<Integer, List<Osobina>> osobineGrouped = null;

	public Map<Integer, List<Osobina>> getOsobineGroupedByTip() {
		if (null == osobineGrouped) {
			osobineGrouped = new HashMap<Integer, List<Osobina>>();
			osobine = osobinaDAO.findByIdTipaObjekta(tipObjekta
					.getIdTipaObjekta());
			for (final Osobina o : osobine) {
				final Integer idTipaOsobine = o.getTipOsobine()
						.getIdTipaOsobine();
				List<Osobina> currList = osobineGrouped.get(idTipaOsobine);
				if (null == currList)
					currList = new ArrayList<Osobina>();
				currList.add(o);
				osobineGrouped.put(idTipaOsobine, currList);
			}
		}
		return osobineGrouped;
	}

	public List<Integer> getOsobinaGroupKeys() {
		osobineGrouped = null;
		final List<Integer> keys = new ArrayList<Integer>();
		keys.addAll(getOsobineGroupedByTip().keySet());
		return keys;
	}

	public List<Posta> getPosteAdrese() {
		return posteAdrese;
	}

	public List<Mjesto> getMjestaAdrese() {
		return mjestaAdrese;
	}

	public void zupanijaObjektaSelected(final ValueChangeEvent vce) {

		mjestaObjekta.clear();
		log.debug("Izabrana: class - " + vce.getNewValue().getClass());

		// immediate = true -- binding u posta items
		soComponents.getPosteObjekta().setValue(
				postaDAO.findAllInZupanija(((Zupanija) vce.getNewValue())
						.getIdZupanje()));

		FacesContext.getCurrentInstance().renderResponse();
	}

	public void postaObjektaSelected(final ValueChangeEvent vce) {
		mjestaObjekta.clear();
		if (null == vce.getNewValue()) {
			return;
		}
		log.debug("Izabrana: class - " + vce.getNewValue().getClass());
		mjestaObjekta.addAll(mjestoDAO
				.findByIdPoste(((Posta) vce.getNewValue()).getIdPoste()));

		FacesContext.getCurrentInstance().renderResponse();
	}

	public void zupanijaAdreseSelected(final ValueChangeEvent vce) {
		mjestaAdrese.clear();

		log.debug("Izabrana: class - " + vce.getNewValue().getClass());

		soComponents.getPosteAdrese().setValue(
				postaDAO.findAllInZupanija(((Zupanija) vce.getNewValue())
						.getIdZupanje()));

		FacesContext.getCurrentInstance().renderResponse();
	}

	public void postaAdreseSelected(final ValueChangeEvent vce) {
		mjestaAdrese.clear();
		if (null == vce.getNewValue()) {
			return;
		}
		log.debug("Izabrana: class - " + vce.getNewValue().getClass());
		mjestaAdrese.addAll(mjestoDAO.findByIdPoste(((Posta) vce.getNewValue())
				.getIdPoste()));

		FacesContext.getCurrentInstance().renderResponse();
	}

	public List<Telefon> getUneseniTelefoni() {
		return uneseniTelefoni;
	}

	public List<EmailAdresa> getUneseneEmailAdrese() {
		return uneseneEmailAdrese;
	}

	public List<Adresa> getUneseneAdrese() {
		return uneseneAdrese;
	}

	public List<Slika> getUneseneSlike() {
		return uneseneSlike;
	}

	public void dodajOpis() {
		opisObjekta.setObjekt(objekt);
		// opisObjekta.setJezik(jezik);
		// UKLONI JEZIK DA GA SE NE MOZE VISE DODATI i POSTAVI NOVU
		// VRIJEDNOST
		jezici.remove(opisObjekta.getJezik());
		if (null == uneseniOpisi) {
			uneseniOpisi = new ArrayList<Opis>();
		}
		uneseniOpisi.add(opisObjekta);
		opisObjekta = new Opis();
		log.debug("Trenutno dodano opisa: " + uneseniOpisi.size());
		FacesContext.getCurrentInstance().renderResponse();
	}

	public void ukloniOpis(final Opis zaUkloniti) {
		log.debug("Uklanjam: " + zaUkloniti.getJezik());
		uneseniOpisi.remove(zaUkloniti);
		if (objekt.getOpisObjektas().contains(zaUkloniti)) {
			objekt.getOpisObjektas().remove(zaUkloniti);
			opisDAO.remove(zaUkloniti);
		}
		jezici.add(zaUkloniti.getJezik());
	}

	public void dodajTelefon() {
		telefon.setObjekt(objekt);
		// UKLONI TIP TELEFONA DA GA SE NE MOZE VISE DODATI i POSTAVI NOVU
		// VRIJEDNOST
		tipoviTelefona.remove(telefon.getTipTelefona());
		if (null == uneseniTelefoni) {
			uneseniTelefoni = new ArrayList<Telefon>();
		}
		uneseniTelefoni.add(telefon);
		telefon = new Telefon();
		log.debug("Trenutno telefona: " + uneseniTelefoni.size());

		FacesContext.getCurrentInstance().renderResponse();
	}

	public void ukloniTelefon(final Telefon zaUkloniti) {
		log.debug("Uklanjam: " + zaUkloniti.getTipTelefona().getNaziv());
		uneseniTelefoni.remove(zaUkloniti);
		if (objekt.getTelefons().contains(zaUkloniti)) {
			objekt.getTelefons().remove(zaUkloniti);
			telefonDAO.remove(zaUkloniti);
		}
		tipoviTelefona.add(zaUkloniti.getTipTelefona());
	}

	public void dodajAdresu() {
		log.debug("Unosim adresu " + adresa.getTipAdrese());

		adresa.setObjekt(objekt);
		// UKLONI TIP ADRESE DA JE SE NE MOZE VISE DODATI i POSTAVI NOVU
		// VRIJEDNOST
		tipoviAdrese.remove(adresa.getTipAdrese());
		if (null == uneseneAdrese) {
			uneseneAdrese = new ArrayList<Adresa>();
		}
		uneseneAdrese.add(adresa);
		adresa = new Adresa();
		log.debug("Trenutno dodano adresa: " + uneseneAdrese.size());

		// FacesContext.getCurrentInstance().renderResponse();
	}

	public void ukloniAdresu(final Adresa zaUkloniti) {
		log.debug("Uklanjam: " + zaUkloniti.getTipAdrese().getNaziv());
		uneseneAdrese.remove(zaUkloniti);
		if (objekt.getAdresas().contains(zaUkloniti)) {
			objekt.getAdresas().remove(zaUkloniti);
			adresaDAO.remove(zaUkloniti);
		}
		tipoviAdrese.add(zaUkloniti.getTipAdrese());

	}

	public void dodajCijenu() {
		log.debug("Unosim cijenu " + cijena);

		if (cijena.getDatumDo().before(cijena.getDatumOd())) {
			facesMessages.addFromResourceBundle("message.datum.poredak");
		}

		cijena.setObjekt(objekt);
		cijene.add(cijena);
		cijena = new Cijena();
		log.debug("Trenutno dodano cijena: " + cijene.size());

		FacesContext.getCurrentInstance().renderResponse();
	}

	public void ukloniCijenu(final Cijena zaUkloniti) {
		log.debug("Uklanjam: " + cijena);
		cijene.remove(zaUkloniti);
		if (objekt.getCijenas().contains(zaUkloniti)) {
			objekt.getCijenas().remove(zaUkloniti);
			cijenaDAO.remove(zaUkloniti);
		}
	}

	public void dodajEmailAdresu() {
		emailAdresa.setObjekt(objekt);
		tipoviEmailAdrese.remove(emailAdresa.getTipEmailAdrese());

		if (null == uneseneEmailAdrese) {
			uneseneEmailAdrese = new ArrayList<EmailAdresa>();
		}
		uneseneEmailAdrese.add(emailAdresa);
		emailAdresa = new EmailAdresa();
		log.debug("Trenutno dodano email adresa: " + uneseneEmailAdrese.size());
		FacesContext.getCurrentInstance().renderResponse();
	}

	public void ukloniEmailAdresu(final EmailAdresa zaUkloniti) {
		log.debug("Uklanjam: " + zaUkloniti.getTipEmailAdrese().getNaziv());
		uneseneEmailAdrese.remove(zaUkloniti);
		if (objekt.getEmailAdresas().contains(zaUkloniti)) {
			objekt.getEmailAdresas().remove(zaUkloniti);
			emailAdresaDAO.remove(zaUkloniti);
		}
		tipoviEmailAdrese.add(zaUkloniti.getTipEmailAdrese());
	}

	public void dodajSliku() {
		log.debug("Unosim sliku " + slika);
		if (slika.getSadrzaj() == null || slika.getSadrzaj().length == 0) {
			slika = new Slika();
			return;
		}
		if (null == uneseneSlike || uneseneSlike.size() == 0) {
			uneseneSlike = new ArrayList<Slika>();
			//if (!otherUserImagesPresent) {
				slika.setPocetna(true);
			//}
		}
		final Korisnik autor = korisnik;
		slika.setKorisnik(autor);
		slika.setObjekt(objekt);
		uneseneSlike.add(slika);
		slika = new Slika();
		FacesContext.getCurrentInstance().renderResponse();
	}

	public void ukloniSliku(final Slika zaUkloniti) {
		log.debug("Uklanjam: " + zaUkloniti.getOpis());
		uneseneSlike.remove(zaUkloniti);
		if (objekt.getSlikas().contains(zaUkloniti)) {
			objekt.getSlikas().remove(zaUkloniti);
			slikaDAO.remove(zaUkloniti);
		}

		slikaAction.deleteImageFromFileSystem(zaUkloniti);

		if (zaUkloniti.isPocetna() && uneseneSlike.size() > 0) {
			uneseneSlike.get(0).setPocetna(true);
		}
	}

	public boolean adekvatan(final Integer tipObjekta, final Integer atribut) {
		boolean res = false;
		switch (atribut) {
		case 1:
			// sobe
			if (tipObjekta == 3 || tipObjekta == 4 || tipObjekta == 5
					|| tipObjekta == 6 || tipObjekta == 7 || tipObjekta == 8
					|| tipObjekta == 9)
				res = true;
			break;
		case 2:
			// prosjecna povrsina kampirnog mjesta
			if (tipObjekta == 1)
				res = true;
			break;
		case 3:
			// broj mjesta za kucice na kotacima
			if (tipObjekta == 1)
				res = true;
			break;
		case 4:
			// broj sanitarnih cvorova
			if (tipObjekta == 1)
				res = true;
			break;
		case 5:
			// osobe ** (kapacitet?)
			res = true;
			break;
		case 6:
			// povrsina smjestaja
			if (tipObjekta == 2 || tipObjekta == 3 || tipObjekta == 4
					|| tipObjekta == 5 	|| tipObjekta == 8)
				res = true;
			break;
		case 7:
			// broj konferencijskih dvorana
			if (tipObjekta == 4)
				res = true;
			break;
		case 8:
			// broj kreveta
			if (tipObjekta == 2 || tipObjekta == 3 || tipObjekta == 4
					|| tipObjekta == 5 || tipObjekta == 6 || tipObjekta == 7
					|| tipObjekta == 8 || tipObjekta == 9)
				res = true;
			break;
		case 9:
			// broj parcela
			if (tipObjekta == 1)
				res = true;
			break;
		case 10:
			// kat * pozicija ili broj? (ja primjenjujem broj katova)
			if (tipObjekta == 2 || tipObjekta == 3)
				res = true;
			break;
		case 11:
			// broj pomocnih kreveta
			if (tipObjekta == 2 || tipObjekta == 3)
				res = true;
			break;
		case 12:
			// bracni krevet * na koje tipove se ovo odnosi
			if (tipObjekta == 2)
				res = true;
			break;
		case 13:
			// jednostruki krevet * na koje tipove se ovo odnosi
			if (tipObjekta == 2)
				res = true;
			break;
		case 14:
			// otvoreno od
			res = true;
			break;
		case 15:
			// otvoreno do
			res = true;
			break;
		case 16:
			// minimalni boravak
			res = true;
			break;
		case 17:
			// vrijeme prijave
			res = true;
			break;
		case 18:
			// vrijeme odjave
			res = true;
			break;
		case 19:
			// broj kupaonica
			if (tipObjekta == 3 || tipObjekta == 5 || tipObjekta == 6
					|| tipObjekta == 7 || tipObjekta == 8 || tipObjekta == 9)
				res = true;
			break;
		case 20:
			// povrsina terase
			if (tipObjekta == 2 || tipObjekta == 3 || tipObjekta == 4
					|| tipObjekta == 5 || tipObjekta == 6 || tipObjekta == 7)
				res = true;
			break;
		case 21:
			// povrsina kampa
			if (tipObjekta == 1)
				res = true;
			break;
		case 22:
			// jednokrevetne sobe
			if (tipObjekta == 3 || tipObjekta == 4 || tipObjekta == 5
					|| tipObjekta == 6 || tipObjekta == 7 || tipObjekta == 8
					|| tipObjekta == 9)
				res = true;
			break;
		case 23:
			// dvokrevetne sobe
			if (tipObjekta == 3 || tipObjekta == 4 || tipObjekta == 5
					|| tipObjekta == 6 || tipObjekta == 7 || tipObjekta == 8
					|| tipObjekta == 9)
				res = true;
			break;
		case 24:
			// trokrevetne sobe
			if (tipObjekta == 3 || tipObjekta == 4 || tipObjekta == 5
					|| tipObjekta == 6 || tipObjekta == 7 || tipObjekta == 8
					|| tipObjekta == 9)
				res = true;
			break;
		case 25:
			// apartmani
			if (tipObjekta == 4 || tipObjekta == 5 || tipObjekta == 6
					|| tipObjekta == 7 || tipObjekta == 9)
				res = true;
			break;
		case 26:
		case 27:
		case 28:
		case 29:
		case 30:
		case 31:
		case 32:
		case 33:
		case 34:
		case 35:
		case 36:
		case 37:
		case 38:
		case 39:
		case 40:
		default:
		}
		return res;
	}

	public boolean obavezan(final Integer tipObjekta, final Integer atribut) {
		boolean res = false;
		switch (atribut) {
		case 8:
			// broj kreveta
			if (tipObjekta == 2 || tipObjekta == 3)
				res = true;
			break;
		case 11:
			// broj pomocnih kreveta
			if (tipObjekta == 3)
				res = true;
			break;
		}
		return res;
	}

	// @Begin(join = true)
	// public String dodajSliku(final Integer idObjekta) {
	// log.debug("Zapocinjem korisnicki prijedlog slike...");
	// objekt = objektDAO.find(idObjekta);
	//
	// if (objekt.getSlikas().size() > 0) {
	// uneseneSlike = new ArrayList<Slika>();
	// otherUserImagesPresent = true;
	// }
	// return "addImage";
	// }

	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public String izmijeniObjekt(final String back) {
		this.back = back;
		log.debug("Zapocinjem korisnicku izmjenu objekta...");
		objekt = objektDAO.find(idObjekta);

		mjesto = objekt.getMjesto();
		zupanija = objekt.getMjesto().getZupanija();
		posta = objekt.getMjesto().getPosta();
		tipObjekta = objekt.getTipObjekta();

		if (null == soComponents.getPosteObjekta()) {
			soComponents.setPosteObjekta(new HtmlSelectItems());
		}
		soComponents.getPosteObjekta().setValue(
				postaDAO.findAllInZupanija(zupanija.getIdZupanje()));

		mjestaObjekta.addAll(mjestoDAO.findByIdPoste(posta.getIdPoste()));

		if (null == uneseneAdrese) {
			uneseneAdrese = new ArrayList<Adresa>();
		} else {
			uneseneAdrese.clear();
		}
		uneseneAdrese.addAll(objekt.getAdresas());
		removeUsedTypes(uneseneAdrese, getTipoviAdrese());
		if (null == uneseneEmailAdrese) {
			uneseneEmailAdrese = new ArrayList<EmailAdresa>();
		} else {
			uneseneEmailAdrese.clear();
		}
		uneseneEmailAdrese.addAll(objekt.getEmailAdresas());
		removeUsedTypes(uneseneEmailAdrese, getTipoviEmailAdrese());
		if (null == uneseniTelefoni) {
			uneseniTelefoni = new ArrayList<Telefon>();
		} else {
			uneseniTelefoni.clear();
		}
		log.debug("Ukupno telefona..." + objekt.getTelefons().size());
		uneseniTelefoni.addAll(objekt.getTelefons());
		removeUsedTypes(uneseniTelefoni, getTipoviTelefona());
		
		if (null == uneseneSlike) {
			uneseneSlike = new ArrayList<Slika>();
		} else {
			uneseneSlike.clear();
		}
		// inicijaliziram lazy kolekciju - NE BRISI OVU LINIJU
		objekt.getSlikas().size();
		uneseneSlike.addAll(objekt.getSlikas());
		if(uneseneSlike.size()>0){
			otherUserImagesPresent = true;
			for (Slika slika : uneseneSlike) {
				slikaAction.readImageFromFileSystem(slika);
			}
		}
		if (null == uneseniOpisi) {
			uneseniOpisi = new ArrayList<Opis>();
		} else {
			uneseniOpisi.clear();
		}
		uneseniOpisi.addAll(objekt.getOpisObjektas());
		removeUsedTypes(uneseniOpisi, getJezici());

		if (null != objekt.getKategorija()) {
			kategorija = objekt.getKategorija();
		}

		if (null != objekt.getSmjestaj()) {
			smjestaj = objekt.getSmjestaj();
		} else {
			smjestaj = new Smjestaj();
		}

		cijene.addAll(objekt.getCijenas());

		for (final Osobina o : objekt.getOsobinas()) {
			osobineMap.put(o.getIdOsobine(), true);
		}

		if (null != objekt.getLatituda())
			latituda = Double.toString(objekt.getLatituda());
		else
			latituda = Double.toString(Drzava.CRO_LATITUDA);
		if (null != objekt.getLongituda())
			longituda = Double.toString(objekt.getLongituda());
		else
			longituda = Double.toString(Drzava.CRO_LONGITUDA);
		if (null != objekt.getZoom())
			zoom = objekt.getZoom();
		else
			zoom = 6;

		editMode = true;
		return "editObjekt";
	}

	@SuppressWarnings("unchecked")
	private void removeUsedTypes(final List typeOwners, final List types) {
		log.debug("Cistim: " + types);
		for (final Iterator i = typeOwners.iterator(); i.hasNext();) {
			final Object owner = i.next();
			if (owner instanceof Adresa) {
				types.remove(((Adresa) owner).getTipAdrese());
			} else if (owner instanceof EmailAdresa) {
				types.remove(((EmailAdresa) owner).getTipEmailAdrese());
			} else if (owner instanceof Telefon) {
				log
						.debug("Tip telefona: "
								+ ((Telefon) owner).getTipTelefona()
										.getIdTipTelefona());

				types.remove(((Telefon) owner).getTipTelefona());
			} else if (owner instanceof Opis) {
				types.remove(((Opis) owner).getJezik());
			} else {
				types.remove(owner);
			}

		}
		log.debug("Nakon ciscenja: " + types);
	}

	// @End
	// @Transactional
	// public String azurirajSlike() {
	// objekt = objektDAO.merge(objekt);
	// if (null != uneseneSlike && uneseneSlike.size() > 0) {
	// objekt.getSlikas().addAll(uneseneSlike);
	// }
	//
	// log.debug("Azuriram objekt....");
	// objektDAO.merge(objekt);
	//
	// log.debug("Registriram akciju u dnevniku aktivnosti objekt....");
	// final DnevnikAktivnosti da = new DnevnikAktivnosti();
	// da.setKorisnik(korisnikDetails);
	// da.setOpis("Azuriranje objekta kroz free web formu");
	// da.setVrijeme(new Date());
	// da.setObjekt(objekt);
	// log.debug("Definiram akciju UPDATE....");
	// da.setAkcija(akcijaDAO.find(new Integer(2)));
	// dnevnikAktivnostiDAO.persist(da);
	//
	// try {
	// pojoCache.remove("objekti", "statistics");
	// pojoCache.remove("objekti", "objektUpdates");
	// pojoCache.remove("objekti", objekt.getIdObjekta());
	// } catch (final CacheException e) {
	// throw new RuntimeException(e.getMessage(), e);
	// }
	//
	// return "next";
	// }

	@End
	@Transactional
	public String azurirajObjekt() {
		objekt = objektDAO.merge(objekt);

		try {
			objekt.setMjesto(mjesto);
			objekt.setTipObjekta(tipObjekta);
			objekt.setLatituda(Double.valueOf(latituda));
			objekt.setLongituda(Double.valueOf(longituda));
			objekt.setZoom(zoom);
			if (null != uneseneAdrese && uneseneAdrese.size() > 0) {
				objekt.getAdresas().addAll(uneseneAdrese);
			}
			if (null != uneseneEmailAdrese && uneseneEmailAdrese.size() > 0) {
				objekt.getEmailAdresas().addAll(uneseneEmailAdrese);
			}
			if (null != uneseniTelefoni && uneseniTelefoni.size() > 0) {
				objekt.getTelefons().addAll(uneseniTelefoni);
			}

			if (null != uneseniOpisi && uneseniOpisi.size() > 0) {
				for (final Iterator<Opis> i = uneseniOpisi.iterator(); i
						.hasNext();) {
					final Opis s = i.next();
					s.setObjekt(objekt);
				}
				objekt.getOpisObjektas().addAll(uneseniOpisi);
			}
			objekt.setStatus(Objekt.Status.NEW.getMark());
			if (null != kategorija) {
				objekt.setKategorija(kategorija);
			}

			objekt.getCijenas().addAll(cijene);

			objekt.getOsobinas().clear();
			for (final Entry<Integer, Boolean> e : osobineMap.entrySet()) {
				final Osobina o = osobinaDAO.find(e.getKey());
				if (e.getValue() == true) {
					objekt.getOsobinas().add(o);
				}
			}

			log.debug("Azuriram objekt....");
			if (null != smjestaj) {
				objekt.setSmjestaj(smjestaj);
			}

			if (objekt.getLongituda().equals(Drzava.CRO_LONGITUDA)) {
				objekt.setLongituda(null);
				objekt.setLatituda(null);
			}

			objektDAO.merge(objekt);
			objektDAO.flush();

			for (Slika slika : uneseneSlike) {
				if(0==slika.getIdSlike()){
					slikaDAO.persist(slika);
					slikaAction.saveImageToFileSystem(slika);
				}
				slikaDAO.flush();
			}

			log.debug("Registriram akciju u dnevniku aktivnosti objekt....");
			final DnevnikAktivnosti da = new DnevnikAktivnosti();
			da.setKorisnik(korisnik);
			da.setOpis("Azuriranje objekta kroz free web formu");
			da.setVrijeme(new Date());
			da.setObjekt(objekt);
			log.debug("Definiram akciju UPDATE....");
			da.setAkcija(akcijaDAO.find(new Integer(2)));
			dnevnikAktivnostiDAO.persist(da);
			dnevnikAktivnostiDAO.flush();

			CacheUtil.clearCache(objekt, currentLang);

			log.debug("Postupak gotov....");
			back = "backToObjekt";
		} catch (final NoResultException e) {
			log.debug(e.getMessage(), e);
		}
		if (back != null) {
			return back;
		} else {
			return "next";
		}
	}

	@Transactional
	@End
	public String zapisiObjekt() {
		log.error("Postupak zapisivanja promjena....");
		suggestStep++;
		if (editMode) {
			final String back = azurirajObjekt();
			editMode = false;
			return back;
		}

		try {
			objekt.setMjesto(mjesto);
			objekt.setTipObjekta(tipObjekta);

			objekt.setLatituda(Double.valueOf(latituda));
			objekt.setLongituda(Double.valueOf(longituda));
			objekt.setZoom(zoom);

			log.debug("Punim objekt....");
			if (null != uneseneAdrese) {
				objekt.getAdresas().addAll(uneseneAdrese);
			}
			if (null != uneseneEmailAdrese) {
				objekt.getEmailAdresas().addAll(uneseneEmailAdrese);
			}
			if (null != uneseniTelefoni) {
				objekt.getTelefons().addAll(uneseniTelefoni);
			}
			// if (null != uneseneSlike && uneseneSlike.size() > 0) {
			// objekt.getSlikas().addAll(uneseneSlike);
			// }
			if (identity.hasRole(Role.ADMIN.toString())
					|| identity.hasRole(Role.POSLOVNI_OGLASIVAC.toString())
					|| identity.hasRole(Role.PRIVATNI_OGLASIVAC.toString())) {
				objekt.setStatus(Objekt.Status.ACCEPTED.getMark());
			} else {
				objekt.setStatus(Objekt.Status.NEW.getMark());
			}
			if (identity.hasRole(Role.POSLOVNI_OGLASIVAC.toString())
					|| identity.hasRole(Role.PRIVATNI_OGLASIVAC.toString())) {
				objekt.setOglasivac(korisnik);
			}
			objekt.setAutor(korisnik);
			objekt.setKategorija(kategorija);
			if (uneseniOpisi != null) {
				objekt.getOpisObjektas().addAll(uneseniOpisi);
			}
			objekt.getCijenas().addAll(cijene);
			for (final Entry<Integer, Boolean> e : osobineMap.entrySet()) {
				if (e.getValue()) {
					final Osobina o = osobinaDAO.find(e.getKey());
					// o.getObjekts().add(objekt);
					objekt.getOsobinas().add(o);
				}
			}

			// specijalna ponuda
			objekt.setIstaknutaPonuda(false);

			if (objekt.getLongituda().equals(Drzava.CRO_LONGITUDA)) {
				objekt.setLongituda(null);
				objekt.setLatituda(null);
			}

			log.debug("Zapisujem objekt....");

			objektDAO.persist(objekt);
			objektDAO.flush();
			objekt.setSmjestaj(smjestaj);
			smjestajDAO.persist(smjestaj);
			// smjestaj.setObjekt(objekt);
			objekt.setCTGID();
			objektDAO.merge(objekt);

			if(null!=uneseneSlike)
			for (Slika slika : uneseneSlike) {
				slikaDAO.persist(slika);
				slikaDAO.flush();
				slikaAction.saveImageToFileSystem(slika);
			}

			log.debug("Registriram akciju u dnevniku aktivnosti objekt....");
			final DnevnikAktivnosti da = new DnevnikAktivnosti();
			da.setKorisnik(korisnik);
			da.setOpis("Dodavanje objekta kroz free web formu");
			da.setVrijeme(new Date());
			da.setObjekt(objekt);
			log.debug("Definiram akciju INSERT....");
			da.setAkcija(akcijaDAO.find(new Integer(1)));
			dnevnikAktivnostiDAO.persist(da);
			log.debug("Registriram nulti posjet....");
			Posjet posjet = new Posjet();
			posjet.setObjekt(objekt);
			posjet.setDatumPosjete(new java.sql.Date((new Date()).getTime()));
			posjetDAO.persist(posjet);

			log.debug("Postupak gotov....");

		} catch (final NoResultException e) {
			log.debug(e.getMessage(), e);
		}

		CacheUtil.clearCache(objekt, currentLang);

		return "next";
	}

	public Objekt getObjekt() {
		return objekt;
	}

	public void setObjekt(final Objekt objekt) {
		this.objekt = objekt;
	}

	public Posta getPosta() {
		return posta;
	}

	public void setPosta(final Posta posta) {
		this.posta = posta;
	}

	public Zupanija getZupanija() {
		return zupanija;
	}

	public void setZupanija(final Zupanija zupanija) {
		this.zupanija = zupanija;
	}

	public Adresa getAdresa() {
		return adresa;
	}

	public void setAdresa(final Adresa adresa) {
		this.adresa = adresa;
	}

	public Telefon getTelefon() {
		return telefon;
	}

	public void setTelefon(final Telefon telefon) {
		this.telefon = telefon;
	}

	public EmailAdresa getEmailAdresa() {
		return emailAdresa;
	}

	public void setEmailAdresa(final EmailAdresa emailAdresa) {
		this.emailAdresa = emailAdresa;
	}

	public Slika getSlika() {
		return slika;
	}

	public void setSlika(final Slika slika) {
		this.slika = slika;
	}

	@Name("soComponents")
	public static class SuggestObjektComponents {
		private UISelectItems posteObjekta;
		private UISelectItems posteAdrese;

		@In(required = false)
		EntityManager entityManager;
		@In(required = false)
		private ObjektSuggestAction objektSuggest;

		public UISelectItems getPosteObjekta() {
			if (null == posteObjekta && null != objektSuggest) {
				if (null != objektSuggest.getZupanija()
						&& null != entityManager) {
					posteObjekta = new HtmlSelectItems();
					posteObjekta.setValue(entityManager.createNamedQuery(
							"Posta.findAllInZupanija").setParameter(1,
							objektSuggest.getZupanija().getIdZupanje())
							.getResultList());
				}
			}

			return posteObjekta;
		}

		public void setPosteObjekta(final UISelectItems posteObjekta) {
			this.posteObjekta = posteObjekta;
		}

		public UISelectItems getPosteAdrese() {
			return posteAdrese;
		}

		public void setPosteAdrese(final UISelectItems posteAdrese) {
			this.posteAdrese = posteAdrese;
		}

	}


	public Kategorija getKategorija() {
		return kategorija;
	}

	public void setKategorija(final Kategorija kategorija) {
		this.kategorija = kategorija;
	}

	/*
	 * public Jezik getJezik() { return jezik; }
	 * 
	 * public void setJezik(final Jezik jezik) { this.jezik = jezik; }
	 */

	public Opis getOpisObjekta() {
		return opisObjekta;
	}

	public void setOpisObjekta(final Opis opisObjekta) {
		this.opisObjekta = opisObjekta;
	}

	public List<Opis> getUneseniOpisi() {
		return uneseniOpisi;
	}

	public void setUneseniOpisi(final List<Opis> uneseniOpisi) {
		this.uneseniOpisi = uneseniOpisi;
	}

	public Mjesto getMjesto() {
		return mjesto;
	}

	public void setMjesto(final Mjesto mjesto) {
		this.mjesto = mjesto;
	}

	public TipObjekta getTipObjekta() {
		return tipObjekta;
	}

	public void setTipObjekta(final TipObjekta tipObjekta) {
		this.tipObjekta = tipObjekta;
	}

	public Cijena getCijena() {
		return cijena;
	}

	public void setCijena(final Cijena cijena) {
		this.cijena = cijena;
	}

	public List<Cijena> getCijene() {
		return cijene;
	}

	public void setCijene(final List<Cijena> cijene) {
		this.cijene = cijene;
	}

	public Smjestaj getSmjestaj() {
		return smjestaj;
	}

	public void setSmjestaj(final Smjestaj smjestaj) {
		this.smjestaj = smjestaj;
	}

	public Map<Integer, Boolean> getOsobineMap() {
		return osobineMap;
	}

	public void processSlika(final UploadEvent ue) {
		log.debug("Unosim slike...");
		for (final UploadItem ui : ue.getUploadItems()) {
			final Slika slika = new Slika();
			slika.setSadrzaj(ui.getData());
			slika.setTipSadrzaja(ui.getContentType());
			log.debug("Unosim sliku " + slika, new Object[0]);
			if (slika.getSadrzaj() == null || slika.getSadrzaj().length == 0) {
				return;
			}
			if (!otherUserImagesPresent) {
				slika.setPocetna(true);
				otherUserImagesPresent=true;
			}
			if (uneseneSlike == null ) {
				uneseneSlike = new ArrayList<Slika>();
			}
			final Korisnik autor = korisnik;
			slika.setKorisnik(autor);
			slika.setObjekt(objekt);
			uneseneSlike.add(slika);
		}
		log.debug("Prisutno slika: " + uneseneSlike.size());
	}

	public String getLatituda() {
		return latituda;
	}

	public void setLatituda(final String latituda) {
		this.latituda = latituda;
	}

	public String getLongituda() {
		return longituda;
	}

	public void setLongituda(final String longituda) {
		this.longituda = longituda;
	}

	public int getZoom() {
		return zoom;
	}

	public void setZoom(final int zoom) {
		this.zoom = zoom;
	}

	public boolean isEditMode() {
		return editMode;
	}

	public void setEditMode(boolean editMode) {
		this.editMode = editMode;
	}

	public int getSuggestStep() {
		return suggestStep;
	}

	public String getSuggestStepPage() {
		log.debug("/guides/objekti/suggest/soS" + suggestStep + ".xhtml");
		return "/guides/objekti/suggest/soS" + suggestStep + ".xhtml";
	}

	public boolean isImmediate() {
		log.error("Step=" + suggestStep + " imediate="
				+ (suggestStep != 1 && suggestStep != 5 && suggestStep != 6));
		return (suggestStep != 1 && suggestStep != 5 && suggestStep != 6);
	}
}
